import React, { Component } from 'react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'))
/**
 * 类组件可以支持状态
 */
class Counter extends Component {
    //编写构造函数，接收属性对象，先把属性对象传递父类的构建函数
    constructor(props) {
        super(props);//super指的就父类的构建函数
        //构造函数中是唯一可以定义状态的地方。也是唯一可以直接给状态对象赋值的地方 this.state = xxx
        //this表示当前的类组件的实例对象 state定死的属性，就表示类组件的状态对象
        this.state = { count: 0 };
    }
    handleClick = () => {
        //我们要想修改类组件的状态，不能直接修改this.state.而是需要通过this.setState方法进行修改
        //通过调用父类里封装好的setState方法设置新状态
        //this.state.count=1;如果直接修改this.state ,则页面不会更新
        //setState除了可以修改状态外，还会当状态改变后自动渲染组件，根据最新的状态计算最新的虚拟DOM
        //也就是React元素，再用最新的虚拟DOM修改真实DOM
        this.setState({ count: ++this.state.count });
    }
    render() {
        //在render方法里，可能使用状态对象中的属性来计算返回的React元素，也就是虚拟DOM
        //状态可以随时间进行变化，也就是说你可以修改状态
        //在React中，给DOM元素绑定事件和原生浏览器略有不同
        // 1.属性变成驼峰命名 onclick=>onClick
        // 2 监听函数也就是回调函数的值从字符串变成了函数对象，或者说函数的引用地址
        return (
            <div>
                <p>{this.state.count}</p>
                <button onClick={this.handleClick}>+</button>
            </div>
        )
    }
}
let element = <Counter />
root.render(element);

/**
 * 首次渲染
 * 1.创建Counter类的实例，调用实例的render 方法，得到返回虚拟DOM
 * {type:'div',props:{children:[{type:'p',children:0},{type:'button'}]}}
 * 2.ReactDOM的 render方法会根据此虚拟DOM生成真实DOM并且插入页面
 * 首次渲染完成
 * 
 * 当点击button的时候，会执行类的实例的handleClick方法，
 * 方法内会调用 this.setState({ count: this.state.count + 1 });
 *   1.计算更新状态 this.state = {count:1}
 *   2.重新渲染组件
 * 重新执行类组件实例的render方法，根据新状态计算新的虚拟DOM
 * {type:'div',props:{children:[{type:'p',children:1},{type:'button'}]}}
 * 为了优化性能，为了减少更新，进行DOM-DIFF算法。比较 新的和老的虚拟DOM的差异
 * 找到差异的部分，得到一个补丁包
 *   更新p的儿子从0到1
 * 会根据补丁包同步或者说更新真实DOM  p.innerHTML = 1;
 * 只会更新p的更新，其它的DOM根本就不会操作，也不会改动
 * 
 * 
 * 
 * 
 * 
 * 
 */